/*
 *  ckr_spec_close_to_comparisons.cpp
 *  ckrSpec
 *
 *  Created by C. Keith Ray on 2006.11.05.
 *  Copyright 2006 __MyCompanyName__. All rights reserved.
 *
 */

#import "ckr_spec_cpp_specs.h"
#import "ckr_spec_cpp.h"

#include <iostream>
#include <sstream>
#include <vector>
#include <deque>

#include <assert.h>

using namespace std;
using namespace ckr;

//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

static void float_not_close_to_in_should_be_close_to_reports_failure();
static void float_close_to_in_should_be_close_to_reports_nothing();

static void float_close_to_in_should_not_be_close_to_reports_failure();
static void float_not_close_to_in_should_not_be_close_to_reports_nothing();

/* SHOULD_BE_CLOSE_TO is implemented in terms of adding/subtracting a 
delta value, so it's only appropriate to floating-point or other 
numerical values. Definately not CStrings. */

//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

void run_close_to_comparison_specs()
{
	float_not_close_to_in_should_be_close_to_reports_failure();
	float_close_to_in_should_be_close_to_reports_nothing();

	float_close_to_in_should_not_be_close_to_reports_failure();
	float_not_close_to_in_should_not_be_close_to_reports_nothing();
}

//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

DECLARE_SPEC(Float_not_close_to_in_should_be_close_to);

void Float_not_close_to_in_should_be_close_to::spec()
{
	VALUE( 102.5 ).SHOULD_BE_CLOSE_TO( 12.0, 0.001 ); // fail msg expected
}

static void float_not_close_to_in_should_be_close_to_reports_failure()
{
	Float_not_close_to_in_should_be_close_to context;
	
	RecordingFailuresSpecListener listener;
	context.run_spec( & listener );

	std::string actual = listener.logStr();
	
	const std::string expected("102.5 (102.5) should be close to 12.0 (12) +/- 0.001 (0.001) FAILED in Float_not_close_to_in_should_be_close_to; line");

	std::string::size_type foundPos = actual.find( expected, 0 );
	assert( foundPos != std::string::npos );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

DECLARE_SPEC(Float_close_to_in_should_be_close_to);

void Float_close_to_in_should_be_close_to::spec()
{
	VALUE( 12.00001 ).SHOULD_BE_CLOSE_TO( 12.0, 0.001 ); // no msg expected
}

static void float_close_to_in_should_be_close_to_reports_nothing()
{
	Float_close_to_in_should_be_close_to context;
	
	RecordingFailuresSpecListener listener;
	context.run_spec( & listener );

	std::string actual = listener.logStr();
	const std::string expected;

	assert( expected == actual );
}

//  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

DECLARE_SPEC(Float_close_to_in_should_not_be_close_to);

void Float_close_to_in_should_not_be_close_to::spec()
{
	VALUE( 12.00001 ).SHOULD_NOT_BE_CLOSE_TO( 12.0, 0.001 ); // fail msg expected
}

static void float_close_to_in_should_not_be_close_to_reports_failure()
{
	Float_close_to_in_should_not_be_close_to context;
	
	RecordingFailuresSpecListener listener;
	context.run_spec( & listener );

	std::string actual = listener.logStr();
	
	const std::string expected("12.00001 (12) should not be close to 12.0 (12) +/- 0.001 (0.001) FAILED in Float_close_to_in_should_not_be_close_to; line");

	std::string::size_type foundPos = actual.find( expected, 0 );
	assert( foundPos != std::string::npos );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

DECLARE_SPEC(Float_not_close_to_in_should_not_be_close_to);

void Float_not_close_to_in_should_not_be_close_to::spec()
{
	VALUE( 12.00001 ).SHOULD_NOT_BE_CLOSE_TO( 102.0, 0.001 ); // fail msg expected
}

void float_not_close_to_in_should_not_be_close_to_reports_nothing()
{
	Float_not_close_to_in_should_not_be_close_to context;
	
	RecordingFailuresSpecListener listener;
	context.run_spec( & listener );

	std::string actual = listener.logStr();
	
	const std::string expected;

	assert( expected == actual );
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

